package com.hello.auth.controller;

import com.hello.auth.form.LoginBody;
import com.hello.auth.form.RegisterBody;
import com.hello.auth.form.RefreshTokenForm;
import com.hello.auth.service.SysLoginService;
import com.hello.common.core.domain.R;
import com.hello.common.core.utils.JwtUtils;
import com.hello.common.core.utils.StringUtils;
import com.hello.common.security.auth.AuthUtil;
import com.hello.common.security.service.TokenService;
import com.hello.common.security.utils.SecurityUtils;
import com.hello.system.api.model.LoginUser;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;


/**
 * token 控制
 * 
 * @author hello
 */
@Slf4j
@RestController
@RequiredArgsConstructor
public class TokenController
{
    private final TokenService tokenService;
    private final SysLoginService sysLoginService;

    @PostMapping("login")
    public R<?> login(@RequestBody LoginBody form)
    {
        log.info("用户登录请求: {}", form.getUsername());
        // 用户登录
        LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
        // 获取登录token
        return R.ok(tokenService.createToken(userInfo));
    }

    @DeleteMapping("logout")
    public R<?> logout(HttpServletRequest request)
    {
        String token = SecurityUtils.getToken(request);
        if (StringUtils.isNotEmpty(token))
        {
            try {
                String username = JwtUtils.getUserName(token);
                log.info("用户退出登录: {}", username);
                
                // 详细记录token信息，帮助调试
                log.debug("退出登录的token: {}, 长度: {}, 格式: {}", 
                    token, token.length(), 
                    token.contains(".") ? "包含" + StringUtils.countMatches(token, ".") + "个点" : "不包含点");
                
                // 获取用户信息
                LoginUser loginUser = tokenService.getLoginUser(token);
                if (loginUser != null) {
                    log.debug("找到登录用户: {}", loginUser.getUsername());
                    
                    // 安全地处理刷新令牌
                    String refreshToken = loginUser.getRefreshToken();
                    if (StringUtils.isNotEmpty(refreshToken)) {
                        try {
                            log.debug("删除刷新令牌: {}", refreshToken);
                            tokenService.delRefreshToken(refreshToken);
                        } catch (Exception e) {
                            log.warn("删除刷新令牌时出错: {}", e.getMessage());
                        }
                    } else {
                        log.debug("用户没有刷新令牌");
                    }
                } else {
                    log.debug("未找到登录用户信息");
                }
                
                // 删除用户缓存记录
                try {
                    AuthUtil.logoutByToken(token);
                    log.debug("已清除用户缓存记录");
                } catch (Exception e) {
                    log.warn("清除用户缓存记录时出错: {}", e.getMessage());
                }
                
                // 记录用户退出日志
                try {
                    sysLoginService.logout(username);
                    log.debug("已记录用户退出日志");
                } catch (Exception e) {
                    log.warn("记录用户退出日志时出错: {}", e.getMessage());
                }
            } catch (Exception e) {
                log.warn("处理退出登录请求时出错", e);
                // 打印详细的token信息以帮助调试
                log.info("问题token详情 - 值: {}, 长度: {}, 格式: {}", 
                    token, token.length(), 
                    token.contains(".") ? "包含" + StringUtils.countMatches(token, ".") + "个点" : "不包含点");
                
                // 即使令牌无效，仍然尝试删除可能的缓存
                try {
                    AuthUtil.logoutByToken(token);
                } catch (Exception ex) {
                    log.debug("清除无效令牌缓存失败: {}", ex.getMessage());
                }
            }
        } else {
            log.warn("退出登录请求中没有提供token");
        }
        return R.ok();
    }

    @PostMapping("refresh")
    public R<?> refresh(@RequestBody RefreshTokenForm form)
    {
        String refreshToken = form.getRefreshToken();
        if (StringUtils.isEmpty(refreshToken))
        {
            return R.fail(401, "刷新令牌不能为空");
        }
        
        log.debug("使用刷新令牌获取新的访问令牌: {}", refreshToken);
        
        // 使用刷新令牌获取新的访问令牌和刷新令牌
        Map<String, Object> tokenInfo = tokenService.refreshTokenAndCreateNew(refreshToken);
        if (tokenInfo == null)
        {
            return R.fail(401, "刷新令牌已过期或无效");
        }
        
        // 删除原刷新令牌
        tokenService.delRefreshToken(refreshToken);
        
        return R.ok(tokenInfo);
    }

    @PostMapping("register")
    public R<?> register(@RequestBody RegisterBody registerBody)
    {
        log.info("用户注册: {}", registerBody.getUsername());
        // 用户注册
        sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
        return R.ok();
    }
}
